home *** CD-ROM | disk | FTP | other *** search
- /* Miscellaneous Internet servers: discard, echo and remote
- * Copyright 1991 Phil Karn, KA9Q
- */
- #include "global.h"
- #include "commands.h"
- #ifndef MSDOS
- #include <time.h>
- #endif
- #include "netuser.h"
- #include "remote.h"
- #include "smtp.h"
- #include "tcp.h"
- #include "nr4.h"
- #include "mailbox.h"
- #include "stats.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: smisc.c,v 1.31 1997/09/07 21:18:28 root Exp root $";
- #endif
-
- char const *Rempass = ""; /* Remote access password */
- char const *RemRTpass = ""; /* Remote access password for adding routes */
-
- extern char *MMotd;
-
- #ifdef ALLSERV
- static void discserv (int s, void *unused, void *p);
- static void echoserv (int s, void *unused, void *p);
- static void quoteserv (int s, void *unused, void *p);
- static void timeserv (int s, void *unused, void *p);
- static void daytimeserv (int s, void *unused, void *p);
- static void handleserver (int s, const char *name, int type);
- #endif
-
- static int chkrpass (struct mbuf * bp, int isaxip);
-
- #ifdef TRACESERVER
- static void traceserv (int s, void *unused, void *p);
- #endif
-
- #ifdef ALLSERV
- char *getquote (void);
- #endif
-
- #ifdef TUTOR
- static void tutorserver (int s, void *mode, void *p);
- #endif
-
- static const char deletenone[] = "The server is not active - nothing to stop!\n";
- static const char openstr[] = "open %s";
- static const char quotehdr[] = "\nQuote-of-the-Day at '%s' on %s\n";
- static const char failedstr[] = "%s failed";
- static const char closestr[] = "close %s";
- static const char discardlistener[] = "Discard listener";
- static const char discardserver[] = "Discard server";
- static const char discardstr[] = "discard";
- static const char timelistener[] = "Time listener";
- static const char timeserver[] = "Time server";
- static const char timestr[] = "time";
- static const char daytimelistener[] = "Daytime listener";
- static const char daytimeserver[] = "Daytime server";
- static const char daytimestr[] = "daytime";
- static const char echolistener[] = "Echo listener";
- static const char echoserver[] = "Echo server";
- static const char echostr[] = "echo";
- static const char tracelistener[] = "Trace listener";
- static const char traceserver[] = "Trace server";
- static const char opentrace[] = "open trace";
- static const char remotelistener[] = "Remote listener";
- static const char passwdfail[] = "PASSWORD FAIL";
- static const char remoteexit[] = "Remote exit %s %s";
- static const char remotekick[] = "Remote kick by %s for host %s";
- static const char remoteroute[] = "Remote route %s attempt from %s for '%s' %s";
- static const char quotelistener[] = "Quote listener";
- static const char quoteserver[] = "Quote server";
- static const char quotestr[] = "quote";
- static const char noopen[] = "Couldn't open '%s'\n";
- static const char telnetstr[] = "telnet";
-
- #ifdef MSDOS
- static const char remotereset[] = "Remote reset %s %s";
- #endif
-
- #ifdef RLOGINSERV
- static const char RLoginlistener[] = "RLogin listener";
- static const char RLoginserver[] = "RLogin server";
- #endif
-
- #ifdef TUTOR
- static const char tutopen[] = "open %s server";
- static const char nonamestr[] = "noname";
- static const char tutclose[] = "close %s server";
- static const char tutorlistener[] = "Tutor listener";
- static const char Tutorserver[] = "Tutor server";
- static const char infolistener[] = "Info listener";
- static const char Infoserver[] = "Info server";
- static const char newslistener[] = "News listener";
- static const char Newsserver[] = "News server";
- #endif
-
-
- static int Rem = -1;
-
-
- void
- server_disconnect_io (void)
- {
- if (Curproc->input != -1) {
- close_s (Curproc->input);
- Curproc->input = -1;
- }
- if (Curproc->output != -1) {
- close_s (Curproc->output);
- Curproc->output = -1;
- }
- }
-
-
-
- int
- deleteserver (int *mysocket)
- {
- if (*mysocket != -1) {
- close_s (*mysocket);
- *mysocket = -1;
- } else
- tputs (deletenone);
- return 0;
- }
-
-
-
- /* Start up a TCP server */
- int
- installserver (
- int argc,
- char *argv[],
- int *mysocket,
- const char *listener,
- int defport,
- uint32 defaddress,
- const char *procname,
- void (*proc) (int, void *, void *),
- unsigned int size,
- void *parm
- ) {
- struct sockaddr_in lsocket;
- int s;
-
- if (*mysocket != -1)
- return 0;
-
- ksignal (Curproc, 0); /* Don't keep the parser waiting */
- chname (Curproc, listener);
-
- lsocket.sin_family = AF_INET;
- lsocket.sin_addr.s_addr = defaddress;
- if (argc < 2)
- lsocket.sin_port = (int16) defport;
- else
- lsocket.sin_port = (int16) atoi (argv[1]);
- *mysocket = socket (AF_INET, SOCK_STREAM, 0);
- (void) bind (*mysocket, (char *) &lsocket, sizeof (lsocket));
- (void) listen (*mysocket, 1);
- server_disconnect_io ();
- for (;;) {
- if ((s = accept (*mysocket, NULLCHAR, (int *) NULL)) == -1)
- break; /* Service is shutting down */
-
- /* Low mem check now done in tcpin.c - WG7J */
- /* Spawn a server */
- (void) newproc (procname, (unsigned int) size, proc, s, parm, NULL, 0);
- }
- return 0;
- }
-
-
-
- #ifdef RLOGINSERV
- static int Srlogin = -1;
- #endif
-
- #ifdef TRACESERVER
- static int Strace = -1;
- #endif
-
- #ifdef TUTOR
- int Stutor = -1;
- int Sinfo = -1;
- int Snews = -1;
- #endif
-
- #ifdef ALLSERV
- static int Sdisc = -1;
- static int Stime = -1;
- static int Squote = -1;
- static int Sdaytime = -1;
- static int Secho = -1;
-
- #define DIFFTIME 2208988800LU
-
- #define T_TIME 0
- #define T_DAYTIME 1
- #define T_DISCARD 2
- #define T_ECHO 3
- #define T_QUOTE 4
-
-
-
- static void
- handleserver (int s, const char *name, int type)
- {
- struct mbuf *bp;
- time_t currtime;
- char buf[32];
- long adjust;
- struct tm *tmp;
-
- (void) sockowner (s, Curproc);
- sprintf (buf, openstr, name);
- log (s, buf);
- switch (type) {
- case T_DISCARD:
- while (recv_mbuf (s, &bp, 0, NULLCHAR, NULL) > 0)
- free_p (bp);
- break;
- case T_QUOTE:
- {
- char buf2[512], *cp;
-
- cp = getquote ();
- currtime = time (&currtime);
- sprintf (buf2, quotehdr, Hostname, ctime (&currtime));
- bp = qdata ((unsigned char *) buf2, (int16) strlen (buf2));
- (void) send_mbuf (s, bp, 0, NULLCHAR, 0);
- bp = qdata ((unsigned char *) cp, (int16) strlen (cp));
- free (cp);
- }
- goto common;
- case T_TIME:
- case T_DAYTIME:
- currtime = time (&currtime);
- tmp = localtime (&currtime);
- if (type == T_DAYTIME) { /* daytime protocol */
- (void) strftime (buf, 32, "%a %b %d, %Y %X %Z\n", tmp);
- bp = qdata ((unsigned char *) buf, (int16) strlen(buf));
- } else {
- /*
- * Change 1970 start time to 1900 start time,
- * and put it in network order
- */
- #if defined(HAVE_TM_ISDST) && !defined(MSDOS)
- adjust = (timezone - (tmp->tm_isdst * 3600L)) / -1L;
- #else
- adjust = tmp->tm_gmtoff;
- #endif
- (void) put32 ((unsigned char *) buf, (uint32) (((uint32)currtime + DIFFTIME) + adjust)); /*lint !e737 */
-
- /* enqueue for transmission */
- bp = qdata ((unsigned char *) buf, sizeof (int32));
- }
- common:
- if (send_mbuf (s, bp, 0, NULLCHAR, 0) == -1) {
- sprintf (buf, failedstr, name);
- log (s, buf);
- }
- break;
- case T_ECHO:
- while (recv_mbuf (s, &bp, 0, NULLCHAR, NULL) > 0)
- (void) send_mbuf (s, bp, 0, NULLCHAR, 0);
- break;
- default:
- break;
- }
- sprintf (buf, closestr, name);
- log (s, buf);
- close_s (s);
- }
-
-
-
- /* Start up TCP discard server */
- int
- dis1 (int argc, char *argv[], void *p OPTIONAL)
- {
- return (installserver (argc, argv, &Sdisc, discardlistener, IPPORT_DISCARD,
- INADDR_ANY, discardserver, discserv, 576, NULL));
- }
-
-
-
- static void
- discserv (int s, void *unused OPTIONAL, void *p OPTIONAL)
- {
- #ifdef STATS_USE
- STATS_adduse (1);
- MiscUsers++;
- #endif
- handleserver (s, discardstr, T_DISCARD);
- #ifdef STATS_USE
- MiscUsers--;
- #endif
- }
-
-
-
- /* Stop discard server */
- int
- dis0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- return (deleteserver (&Sdisc));
- }
-
-
-
- /* Start up TCP time server */
- int
- time1 (int argc, char *argv[], void *p OPTIONAL)
- {
- return (installserver (argc, argv, &Stime, timelistener, IPPORT_TIME,
- INADDR_ANY, timeserver, timeserv, 512, NULL));
- }
-
-
-
- static void
- timeserv (int s, void *unused OPTIONAL, void *p OPTIONAL)
- {
- (void) sockmode (s, SOCK_BINARY);
- handleserver (s, timestr, T_TIME);
- }
-
-
-
- /* Stop time server */
- int
- time0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- return (deleteserver (&Stime));
- }
-
-
-
- /* Start up TCP daytime server */
- int
- daytime1 (int argc, char *argv[], void *p OPTIONAL)
- {
- return (installserver (argc, argv, &Sdaytime, daytimelistener, IPPORT_DAYTIME,
- INADDR_ANY, daytimeserver, daytimeserv, 576, NULL));
- }
-
-
-
- static void
- daytimeserv (int s, void *unused OPTIONAL, void *p OPTIONAL)
- {
- handleserver (s, daytimestr, T_DAYTIME);
- }
-
-
-
- /* Stop time server */
- int
- daytime0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- return (deleteserver (&Sdaytime));
- }
-
-
-
- /* Start up TCP echo server */
- int
- echo1 (int argc, char *argv[], void *p OPTIONAL)
- {
- return (installserver (argc, argv, &Secho, echolistener, IPPORT_ECHO,
- INADDR_ANY, echoserver, echoserv, 2048, NULL));
- }
-
-
-
- static void
- echoserv (int s, void *unused OPTIONAL, void *p OPTIONAL)
- {
- #ifdef STATS_USE
- STATS_adduse (1);
- MiscUsers++;
- #endif
- handleserver (s, echostr, T_ECHO);
- #ifdef STATS_USE
- MiscUsers--;
- #endif
- }
-
-
-
- /* stop echo server */
- int
- echo0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- return (deleteserver (&Secho));
- }
- #endif /*ALLSERV*/
-
-
-
-
- #if defined(TRACESERVER) || defined(ENCAP)
- extern struct cmds Cmds[];
- #endif
-
-
- #ifdef TRACESERVER
-
- /* Start up TCP trace server */
- int
- trace1 (int argc, char *argv[], void *p OPTIONAL)
- {
- return (installserver (argc, argv, &Strace, tracelistener, IPPORT_TRACE,
- INADDR_ANY, traceserver, traceserv, 1024, NULL));
- }
-
-
-
- /* Stop trace server */
- int
- trace0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- return (deleteserver (&Strace));
- }
-
-
-
- static void
- traceserv (int s, void *unused OPTIONAL, void *p OPTIONAL)
- {
- #define CMDLINE 80
- char *cmd;
- int outsave, insave;
-
- #ifdef STATS_USE
- STATS_adduse (1);
- MiscUsers++;
- #endif
- (void) sockowner (s, Curproc);
- log (s, opentrace);
- outsave = Curproc->output;
- Curproc->output = s;
- insave = Curproc->input;
- Curproc->input = s;
-
- /* allocate the command buffer */
- cmd = mallocw (CMDLINE + 1);
-
- while (recvline (s, (unsigned char *) cmd, CMDLINE) > 0) {
- if (!strnicmp ("tr", cmd, 2)) /* only allow 'trace' command ! */
- (void) cmdparse (Cmds, cmd, NULL);
- if (!strnicmp ("ex", cmd, 2))
- break;
- }
- removetrace ();
- Curproc->input = insave;
- Curproc->output = outsave;
- log (s, "close trace");
- #ifdef STATS_USE
- MiscUsers--;
- #endif
- close_s (s);
- }
- #endif /* TRACESERVER */
-
-
-
- /* Start remote exit/reboot server */
- int
- rem1 (int argc, char *argv[], void *p OPTIONAL)
- {
- struct sockaddr_in lsocket, fsock;
- int i;
- int command;
- struct mbuf *bp, **bpp;
- uint32 addr;
- char temp[80], cmdbuf[128];
- int len;
- int action;
- char *ab, *cp;
- int badaddr;
-
- if (Rem != -1)
- return 0;
- ksignal (Curproc, 0);
- chname (Curproc, remotelistener);
- server_disconnect_io ();
- lsocket.sin_family = AF_INET;
- lsocket.sin_addr.s_addr = INADDR_ANY;
- if (argc < 2)
- lsocket.sin_port = IPPORT_REMOTE;
- else
- lsocket.sin_port = (int16) atoi (argv[1]);
-
- Rem = socket (AF_INET, SOCK_DGRAM, 0);
- (void) bind (Rem, (char *) &lsocket, sizeof (lsocket));
- for (;;) {
- i = sizeof (fsock);
- if (recv_mbuf (Rem, &bp, 0, (char *) &fsock, &i) == -1)
- break;
- bpp = &bp;
- command = PULLCHAR (bpp);
-
- switch (command) {
- #ifdef MSDOS /* Only present on PCs running MSDOS */
- case SYS_RESET:
- i = chkrpass (bp, 0);
- log (Rem, remotereset, psocket ((struct sockaddr *) &fsock),
- i == 0 ? passwdfail : "");
- if (i != 0) {
- /*Indicate a hardware reset*/
- where_outta_here (2, "rem1");
- }
- break;
- #endif
- case SYS_EXIT:
- i = chkrpass (bp, 0);
- log (Rem, remoteexit, psocket ((struct sockaddr *) &fsock), (i == 0) ? passwdfail : "");
- if (i != 0) /*No reset*/
- where_outta_here (0, "rem1");
- break;
- case KICK_ME:
- if (len_p (bp) >= sizeof (int32))
- addr = pull32 (&bp);
- else
- addr = fsock.sin_addr.s_addr;
-
- /* get round strange printf bug */
- strncpy (temp, inet_ntoa (addr), 20);
-
- log (Rem, remotekick, psocket ((struct sockaddr *) &fsock), temp);
- #ifdef NETROM
- donodetick (); /* g3rra's idea!..hmmm */
- #endif /* NETROM */
- (void) kick (addr);
- smtptick ((void *) addr);
- break;
- #ifdef ENCAP
- case ROUTE_ADD:
- case ROUTE_DROP:
- action = (command == ROUTE_ADD) ? 1 : 0;
-
- /* first, extract the route string */
- len = PULLCHAR (bpp); /* get the length of the name portion */
- if (len > 18)
- break;
- (void) pullup (bpp, (unsigned char *) temp, (int16) len);
- temp[len] = 0;
-
- /* now check the password */
- i = chkrpass (bp, 1);
-
- ab = psocket ((struct sockaddr *) &fsock);
- if ((cp = strchr (ab, ':')) != NULLCHAR)
- *cp = 0;
- badaddr = (strcmp (ab, "127.0.0.1")) ? 0 : 1;
- if (badaddr && action)
- tcmdprintf ("Attempt to add remote route to 127.0.0.1 - ignored\n");
-
- log (Rem, remoteroute, (action) ? "add" : "drop", ab, temp, (badaddr) ? "cannot route to 127.0.0.1" : (i == 0) ? passwdfail : "");
-
- if (strncmp (temp, "44.", 3) || !strncmp (ab, "44.", 3) || aton(temp) == 0)
- i = 0; /* disable if route not for amprnet or from amprnet (error) */
-
- if (i != 0) {
- /* add/drop the route */
- if (action)
- sprintf (cmdbuf, "route addp %s encap %s", temp, ab);
- else
- sprintf (cmdbuf, "route drop %s", temp);
- (void) cmdparse (Cmds, cmdbuf, NULL);
- }
- break;
- #endif
- default:
- break;
- }
- #if 0 /* deliberate memory leak */
- free_p (bp);
- #endif
- }
- close_s (Rem);
- Rem = -1;
- return 0;
- }
-
-
-
- /* Check remote password */
- static int
- chkrpass (struct mbuf *bp, int isaxip)
- {
- char *lbuf;
- int16 len;
- int rval = 0;
-
- len = len_p (bp);
- if (!isaxip) {
- if (strlen (Rempass) == 0 || strlen (Rempass) != len)
- return rval;
- } else {
- if (strlen (RemRTpass) == 0 || strlen (RemRTpass) != len)
- return rval;
- }
- lbuf = mallocw (len);
- (void) pullup (&bp, (unsigned char *) lbuf, len);
- if (strncmp ((!isaxip) ? Rempass : RemRTpass, lbuf, len) == 0)
- rval = 1;
- free (lbuf);
- return rval;
- }
-
-
-
- int
- rem0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- close_s (Rem);
- return 0;
- }
-
-
-
- #ifdef ALLSERV
- /* Start up TCP quote server */
- int
- quote1 (int argc, char *argv[], void *p OPTIONAL)
- {
- return (installserver (argc, argv, &Squote, quotelistener, IPPORT_QUOTE,
- INADDR_ANY, quoteserver, quoteserv, 1536, NULL));
- }
-
-
-
- static void
- quoteserv (int s, void *unused OPTIONAL, void *p OPTIONAL)
- {
- handleserver (s, quotestr, T_QUOTE);
- }
-
-
-
- /* Stop quote server */
- int
- quote0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- return (deleteserver (&Squote));
- }
-
-
-
- char *
- getquote ()
- {
- char buf2[512];
- char searchstr[8];
- char buf3[4096];
- char *cptr;
- FILE *fp;
- struct date dt;
-
- if (Squote == -1)
- return (NULLCHAR);
- if ((fp = fopen (Quotes, READ_TEXT)) == NULLFILE) {
- if (MMotd != NULLCHAR)
- return (strdup (MMotd));
- else
- return (NULLCHAR);
- }
- tnos_getdate (&dt);
- sprintf (searchstr, "[%-d]", dt.da_day);
- while (fgets (buf2, 512, fp) != NULLCHAR) {
- if (!strncmp (searchstr, buf2, strlen (searchstr)))
- break;
- }
- buf3[0] = 0;
- if ((cptr = strchr (buf2, '%')) != NULLCHAR) {
- rip (buf2);
- (void) fclose (fp);
- if ((fp = fopen (++cptr, READ_TEXT)) == NULLFILE) {
- tcmdprintf (noopen, &buf2[1]);
- return (NULLCHAR);
- }
- }
- while (fgets (buf2, 512, fp) != NULLCHAR) {
- if (*buf2 == '[')
- break;
- strcat (buf3, buf2);
- }
- (void) fclose (fp);
- return (strdup (buf3));
- }
- #endif /* ALLSERV */
-
-
-
- /* Execute user quote command */
- int
- doquote (int argc OPTIONAL, char *argv[], void *p)
- {
- free (argv[0]);
- argv[0] = strdup (telnetstr);
- if (argv[2])
- free (argv[2]);
- argv[2] = strdup ("17");
- if (!argv[1])
- argv[1] = strdup (Hostname);
- return dotelnet (3, argv, p);
- }
-
-
-
- #ifdef RLOGINSERV
- /* Start up RLOGIN server */
- int
- rlogin1 (int argc, char *argv[], void *p OPTIONAL)
- {
- return (installserver (argc, argv, &Srlogin, RLoginlistener, IPPORT_RLOGIN,
- INADDR_ANY, RLoginserver, pbbs_incom, 2048, (void *) RLOGIN_LINK));
- }
-
-
-
- /* Stop RLOGIN server */
- int
- rlogin0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- return (deleteserver (&Srlogin));
- }
- #endif
-
-
-
- #ifdef TUTOR
- extern void tutorserv (const char *, struct mbx *, int, int, int);
- static const char *tut[] = {"tutor", "info", "news"};
-
-
-
- static void
- tutorserver (int s, void *mode, void *p OPTIONAL)
- {
- int outsave, insave;
-
- (void) sockmode (s, SOCK_ASCII);
- (void) sockowner (s, Curproc);
- log (s, tutopen, tut[(int) mode]);
- outsave = Curproc->output;
- Curproc->output = s;
- insave = Curproc->input;
- Curproc->input = s;
- tutorserv (nonamestr, NULLMBX, (int) mode, 0, 1);
- Curproc->input = insave;
- Curproc->output = outsave;
- log (s, tutclose, tut[(int) mode]);
- close_s (s);
- }
-
-
-
- /* Start up TCP tutorial server */
- int
- tutor1 (int argc, char *argv[], void *p OPTIONAL)
- {
- return (installserver (argc, argv, &Stutor, tutorlistener, IPPORT_TUTOR,
- INADDR_ANY, Tutorserver, tutorserver, 2048, (void *) 0));
- }
-
-
-
- /* Stop tutorial server */
- int
- tutor0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- return (deleteserver (&Stutor));
- }
-
-
-
- /* Start up TCP tutorial server */
- int
- info1 (int argc, char *argv[], void *p OPTIONAL)
- {
- return (installserver (argc, argv, &Sinfo, infolistener, IPPORT_INFO,
- INADDR_ANY, Infoserver, tutorserver, 2048, (void *) 1));
- }
-
-
-
- /* Stop tutorial server */
- int
- info0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- return (deleteserver (&Sinfo));
- }
-
-
-
- /* Start up TCP news server */
- int
- news1 (int argc, char *argv[], void *p OPTIONAL)
- {
- return (installserver (argc, argv, &Snews, newslistener, IPPORT_NEWS,
- INADDR_ANY, Newsserver, tutorserver, 2048, (void *) 2));
- }
-
-
-
- /* Stop news server */
- int
- news0 (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- return (deleteserver (&Snews));
- }
-
-
-
- static char WhichTutor = 0;
-
-
-
- /* Execute user tutor command */
- int
- dotutor (int argc OPTIONAL, char *argv[], void *p)
- {
- char buf[6];
- int i = WhichTutor;
-
- WhichTutor = 0;
- free (argv[0]);
- argv[0] = strdup (telnetstr);
- if (argv[2])
- free (argv[2]);
- sprintf (buf, "%-d", IPPORT_TUTOR - i);
- argv[2] = strdup (buf);
- if (!argv[1])
- argv[1] = strdup (Hostname);
- return dotelnet (3, argv, p);
- }
-
-
-
- /* Execute user info command */
- int
- doinfo (int argc, char *argv[], void *p)
- {
- WhichTutor = 1;
- return (dotutor (argc, argv, p));
- }
-
-
-
- /* Execute user info command */
- int
- donews (int argc, char *argv[], void *p)
- {
- WhichTutor = 2;
- return (dotutor (argc, argv, p));
- }
-
-
- #endif
-
-
-